package com.yida.common.core.utils;

import cn.hutool.core.util.StrUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.lang.reflect.Method;
import java.util.Optional;

/**
 * spel工具类
 *
 * @author liangp
 * @date 2023/03/02
 */
public class SpelUtils {

    /**
     * 获取aop参数,映射参数名称
     *
     * @param standardEvaluationContext
     * @param joinPoint
     * @return
     */
    public static StandardEvaluationContext setContextVariables(StandardEvaluationContext standardEvaluationContext, JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method targetMethod = methodSignature.getMethod();
        //LocalVariableTableParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
        //String[] parametersName = parameterNameDiscoverer.getParameterNames(targetMethod);
        DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
        String[] parametersName = discoverer.getParameterNames(targetMethod);
        if (args == null || args.length <= 0) {
            return standardEvaluationContext;
        }
        for (int i = 0; i < args.length; i++) {
            standardEvaluationContext.setVariable(parametersName[i], args[i]);
        }
        return standardEvaluationContext;
    }

    /**
     * 通过key SEL表达式获取值
     */
    public static <T> Optional<T> getElValue(Class<T> t, String key, StandardEvaluationContext context) {
        if (StrUtil.isBlank(key)) {
            return Optional.empty();
        }
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(key);
        return Optional.ofNullable(exp.getValue(context, t));
    }

}
